// #include "gps.hpp"

// #include <iostream>

// #include "message/gga.hpp"
// #include "message/gsa.hpp"
// #include "message/gsv.hpp"
// #include "message/rmc.hpp"
// #include "message/zda.hpp"
// #include "spdlog/spdlog.h"

// DownGPSData::DownGPSData() : la_(0), longti_(0), utc_(0), al_(0) {}
// DownGPSData::DownGPSData(double la, double longti, int utc, double al)
//     : la_(la), longti_(longti), utc_(utc), al_(al) {}

// component::Nmea GPS::ParseSingleSentence(const std::string& str) {
//   component::Nmea info;
//   if (str.find('$', 0) == std::string::npos) return info;
//   nmea::sentence sentence(str);

//   std::string type = sentence.type();
//   if (type == "GGA") {
//     nmea::gga gga(sentence);
//     info.type = component::NmeaType::kGGA;
//     if (gga.latitude.exists() && gga.longitude.exists()) {
//       info.la = gga.altitude.get();
//       info.lon = gga.longitude.get();
//     }
//     if (gga.altitude.exists()) altitude_ = gga.altitude.get();
//     return info;
//   }

//   else if (type == "RMC") {
//     nmea::rmc rmc(sentence);
//     info.type = component::NmeaType::kRMC;
//     if (rmc.latitude.exists() && rmc.longitude.exists()) {
//       info.la = rmc.latitude.get();
//       info.lon = rmc.longitude.get();
//     }
//     if (rmc.utc.exists()) utc_ = rmc.utc.get();
//     return info;
//   }

//   else if (type == "TXT") {
//     info.type = component::NmeaType::kTXT;
//   } else {
//     SPDLOG_DEBUG("{}: {}", type, sentence.nmea_string());
//   }
//   return info;
// }

// void GPS::ThreadRecv() {
//   SPDLOG_INFO("[ThreadRecv] Started.");

//   std::size_t start = 0, end = 0;
//   bool find_npos = true;

//   while (thread_continue_) {
//     std::this_thread::sleep_for(std::chrono::milliseconds(90));
//     char raw_str[1024];
//     memset(raw_str, '1', sizeof(raw_str));

//     mutex_.lock();
//     // if (serial_.Recv(&raw_str, 1024) > 0) {
//     if (true) {
//       std::string rpt(raw_str);

//       while (find_npos) {
//         if (end != std::string::npos) start = rpt.find('$', end);
//         if (start != std::string::npos) end = rpt.find("\n", start);

//         find_npos = !(start == std::string::npos || end == std::string::npos);
//         // 若'$'和'\n'有未找到，则find_npos = false

//         if (find_npos)
//           SPDLOG_DEBUG("start {}, end {}, find_npos {}", start, end, find_npos);
//         else {
//           start = end = 0;
//           find_npos = true;
//           SPDLOG_DEBUG("npos");
//           break;
//         }
//         auto sub = rpt.substr(start, end - start);

//         SPDLOG_DEBUG("GPS sub   {} ", sub);
//         SPDLOG_DEBUG("GPS size  {} ", sub.size());
//         commandq_.emplace_back(ParseSingleSentence(sub));
//         signal_.Signal();
//       }
//     }
//     mutex_.unlock();
//   }
//   SPDLOG_WARN("End");
// }

// GPS::GPS() { SPDLOG_TRACE("Constructed."); }

// GPS::GPS(bool start) {
//   Init(start);
//   SPDLOG_TRACE("Constructed.");
// }

// GPS::~GPS() {
//   Close();
//   thread_recv_.join();
//   SPDLOG_TRACE("Destructed.");
// }

// bool GPS::Init(bool start) {
//   // serial_.Open(USBDevice::kDEVICE_GPS);
//   // auto ret =
//   //     serial_.Config(false, StopBits::kSTOP_BITS_1, DataLength::kDATA_LEN_8,
//   //                    false, BaudRate::kBAUD_RATE_115200);
//   // assert(ret);
//   utc_ = 0;
//   altitude_ = 0;
//   thread_continue_ = start;
//   thread_recv_ = std::thread(&GPS::ThreadRecv, this);
//   signal_.Init();
//   SPDLOG_INFO("Opened");
//   // return ret;
//   return true;
// }

// bool GPS::Close() {
//   // serial_.Close();
//   thread_continue_ = false;
//   return !thread_continue_;
// }

// const component::Nmea GPS::GetData() {
//   signal_.Wait();
//   component::Nmea pack;
//   SPDLOG_DEBUG("Waited");
//   if (!commandq_.empty()) {
//     pack = commandq_.back();
//     commandq_.clear();
//   }
//   return pack;
// }

// const int& GPS::GetTimeStamp() {
//   SPDLOG_DEBUG("UTC : {}", utc_);
//   return utc_;
// }

// const double& GPS::GetAltitude() {
//   SPDLOG_DEBUG("Altitude : {}", altitude_);
//   return altitude_;
// }

// const std::vector<double>& GPS::GetDownGPSDataVec() {
//   std::vector<double> datas = {0, 0, 0, 0};
//   if (commandq_.size() > 0) {
//     component::Nmea nmea = commandq_.back();
//     datas[0] = nmea.la;
//     datas[1] = nmea.lon;
//     datas[2] = GetAltitude();
//     datas[3] = GetTimeStamp();
//   }
//   return std::ref(datas);
// }

// DownGPSData GPS::GetDownGPSData() {
//   DownGPSData data;
//   if (commandq_.size() > 0) {
//     component::Nmea nmea = commandq_.back();
//     data.al_ = GetAltitude();
//     data.la_ = nmea.la;
//     data.longti_ = nmea.lon;
//     data.utc_ = GetTimeStamp();
//   }
//   return data;
// }